package other.xsy.paas.utils;


import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**功能描述：日期工具类
 * @ClassName: HCDateUtils	
 * @Description: 日期工具类
 * @author 范伟绵
 * @date 2021年12月03日
 */

public class HCDateUtils {

    public static String FORMATTIME = "yyyy-MM-dd HH:mm:ss";
    public static String FORMAT = "yyyy-MM-dd";

    /**
     * Long类型时间->转换成日期->转成要求格式的String类型
     */
    public static String fromLongToDate(String format, Long time) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date date = new Date(time);
        return sdf.format(date);
    }

	/**
     * 根据开始时间和结束时间返回时间段内的时间集合
     *
     * @param start
     * @param end
     * @return List
     */
    public static List<Date> getDatesBetweenTwoDate(String start, String end) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date beginDate = sdf.parse(start);
        Date endDate = sdf.parse(end);
        if (beginDate.compareTo(endDate) > 0) {
            Date tmp = endDate;
            endDate = beginDate;
            beginDate = tmp;
        }
        List<Date> lDate = new ArrayList<Date>();
        lDate.add(beginDate);// 把开始时间加入集合
        Calendar cal = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        cal.setTime(beginDate);
        boolean bContinue = true;
        while (bContinue) {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            cal.add(Calendar.DAY_OF_MONTH, 1);
            // 测试此日期是否在指定日期之后
            if (endDate.after(cal.getTime())) {
                lDate.add(cal.getTime());
            } else {
                break;
            }
        }
        lDate.add(endDate);// 把结束时间加入集合
        return lDate;
    }
    
    /**
     * 根据开始时间和结束时间返回时间段内的月份集合
     *
     * @param start
     * @param end
     * @return List
     */
    public static List<String> getMonthBetweenTwoDate(String start, String end) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date beginDate = sdf.parse(start);
        Date endDate = sdf.parse(end);
        if (beginDate.compareTo(endDate) > 0) {
            Date tmp = endDate;
            endDate = beginDate;
            beginDate = tmp;
        }
        List<String> lDate = new ArrayList<String>();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(beginDate);
        int startYear = calendar.get(Calendar.YEAR);
        int startMonth = calendar.get(Calendar.MONTH);
        calendar.setTime(endDate);
        int endYear = calendar.get(Calendar.YEAR);
        int endMonth = calendar.get(Calendar.MONTH);
        for (int i = startYear; i <= endYear; i++) {
            String date = "";
            if (startYear == endYear) {
                for (int j = startMonth; j <= endMonth; j++) {
                    if (j < 9) {
                        date = i+"-0"+ (j+1);
                    } else {
                        date = i+"-"+ (j+1);
                    }
                    lDate.add(date);
                }
            } else {
                if (i == startYear){
                    for (int j = startMonth; j < 12; j++) {
                        if (j < 9) {
                            date = i+"-0"+ (j+1);
                        } else {
                            date = i+"-"+ (j+1);
                        }
                        lDate.add(date);
                    }
                } else if (i == endYear) {
                    for (int j = 0; j <= endMonth; j++) {
                        if (j < 9) {
                            date = i+"-0"+ (j+1);
                        } else {
                            date = i+"-"+ (j+1);
                        }
                        lDate.add(date);
                    }
                } else {
                    for (int j = 0; j < 12; j++) {
                        if (j < 9) {
                            date = i+"-0"+ (j+1);
                        } else {
                            date = i+"-"+ (j+1);
                        }
                        lDate.add(date);
                    }
                }

            }
        }

        return lDate;
    }
    
    
 // date类型转换为String类型
  	// formatType格式为yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日 HH时mm分ss秒
  	// data Date类型的时间
  	public static String dateToString(Date data, String formatType) {
  		return new SimpleDateFormat(formatType).format(data);
  	}
  
  	// long类型转换为String类型
  	// currentTime要转换的long类型的时间
  	// formatType要转换的string类型的时间格式
  	public static String longToString(long currentTime, String formatType)
  			throws ParseException {
  		Date date = longToDate(currentTime, formatType); // long类型转成Date类型
  		String strTime = dateToString(date, formatType); // date类型转成String
  		return strTime;
  	}
  
  	// string类型转换为date类型
  	// strTime要转换的string类型的时间，formatType要转换的格式yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日
  	// HH时mm分ss秒，
  	// strTime的时间格式必须要与formatType的时间格式相同
  	public static Date stringToDate(String strTime, String formatType)
  			throws ParseException {
  		SimpleDateFormat formatter = new SimpleDateFormat(formatType);
  		Date date = null;
  		date = formatter.parse(strTime);
  		return date;
  	}
  
  	// long转换为Date类型
  	// currentTime要转换的long类型的时间
  	// formatType要转换的时间格式yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日 HH时mm分ss秒
  	public static Date longToDate(long currentTime, String formatType)
  			throws ParseException {
  		Date dateOld = new Date(currentTime); // 根据long类型的毫秒数生命一个date类型的时间
  		String sDateTime = dateToString(dateOld, formatType); // 把date类型的时间转换为string
  		Date date = stringToDate(sDateTime, formatType); // 把String类型转换为Date类型
  		return date;
  	}
  
  	// string类型转换为long类型
  	// strTime要转换的String类型的时间
  	// formatType时间格式
  	// strTime的时间格式和formatType的时间格式必须相同
  	public static long stringToLong(String strTime, String formatType)
  			throws ParseException {
  		Date date = stringToDate(strTime, formatType); // String类型转成date类型
  		if (date == null) {
  			return 0;
  		} else {
  			long currentTime = dateToLong(date); // date类型转成long类型
  			return currentTime;
  		}
  	}
  
  	// date类型转换为long类型
  	// date要转换的date类型的时间
  	public static long dateToLong(Date date) {
  		return date.getTime();
  	}
  	
    /** 
     * 计算两个日期之间相差的天数 
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException 
     */  
    public static int daysBetween(Date smdate,Date bdate) throws ParseException  
    {  
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        smdate=sdf.parse(sdf.format(smdate));
        bdate=sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();  
        cal.setTime(smdate);  
        long time1 = cal.getTimeInMillis();               
        cal.setTime(bdate);  
        long time2 = cal.getTimeInMillis();       
        long between_days=(time2-time1)/(1000*3600*24);
          
       return Integer.parseInt(String.valueOf(between_days));         
    }  
    
    /**
　　 *字符串的日期格式的计算
　　 */
    public static int daysBetween(String smdate,String bdate) throws ParseException{
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();  
        cal.setTime(sdf.parse(smdate));  
        long time1 = cal.getTimeInMillis();               
        cal.setTime(sdf.parse(bdate));  
        long time2 = cal.getTimeInMillis();       
        long between_days=(time2-time1)/(1000*3600*24);
          
       return Integer.parseInt(String.valueOf(between_days));   
    }
    
    /**
     * 
     * @param time
     *           时间
     * @param num
     *           加的数，-num就是减去
     * @return 
     *          减去相应的数量的月份的日期
     * @throws ParseException Date
     */
    public static Date monthAddNum(Date time, Integer num){
        //SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //Date date = format.parse(time);
        
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.add(Calendar.MONTH, num);
        Date newTime = calendar.getTime();
        return newTime;
    }
    
    /** 
     * 把符合日期格式的字符串转换为日期类型 
     *  
     * @param dateStr 
     * @return 
     */ 
    public static Date stringtoDate(String dateStr, String format) {
        Date d = null; 
        SimpleDateFormat formater = new SimpleDateFormat(format); 
        try { 
            formater.setLenient(false); 
            d = formater.parse(dateStr); 
        } catch (Exception e) { 
            // log.error(e); 
            d = null; 
        } 
        return d; 
    } 
  
    /** 
     * 获取某年某月的天数 
     *  
     * @param year 
     *          int 
     * @param month 
     *          int 月份[1-12] 
     * @return int 
     */ 
    public static int getDaysOfMonth(int year, int month) { 
        Calendar calendar = Calendar.getInstance(); 
        calendar.set(year, month - 1, 1); 
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH); 
    } 

    /** 
     * 返回日期的天 
     *  
     * @param date 
     *          Date 
     * @return int 
     */ 
    public static int getDay(Date date) { 
        Calendar calendar = Calendar.getInstance(); 
        calendar.setTime(date); 
        return calendar.get(Calendar.DATE); 
    } 
  
    /** 
     * 返回日期的年 
     *  
     * @param date 
     *          Date 
     * @return int 
     */ 
    public static int getYear(Date date) { 
        Calendar calendar = Calendar.getInstance(); 
        calendar.setTime(date); 
        return calendar.get(Calendar.YEAR); 
    } 
  
    /** 
     * 返回日期的月份，1-12 
     *  
     * @param date 
     *          Date 
     * @return int 
     */ 
    public static int getMonth(Date date) { 
        Calendar calendar = Calendar.getInstance(); 
        calendar.setTime(date); 
        return calendar.get(Calendar.MONTH) + 1; 
    } 
  
    /** 
     * 计算两个日期相差的天数，如果date2 > date1 返回正数，否则返回负数 
     *  
     * @param date1 
     *          Date 
     * @param date2 
     *          Date 
     * @return long 
     */ 
    public static long dayDiff(Date date1, Date date2) { 
        return (date2.getTime() - date1.getTime()) / 86400000; 
    } 
    
    /** 
     * 获取多少天以前的日期（LONG）
     *  
     * @param amount 
     *          int：多少天 
     * @return long 
     */ 
    public static Long getDaysBeforeLong(int amount) {
		 Calendar calendar1 = Calendar.getInstance();
		 calendar1.add(Calendar.DATE, -amount);
		 return  calendar1.getTime().getTime(); 
	}
    
    /** 
     * 获取多少天以前的日期（String）
     *  
     * @param amount 
     *          int：多少天 
     * @return String 
     */ 
    public static String getDaysBeforeString(int amount) {
    	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		Calendar cld = Calendar.getInstance();
		cld.setTime(new Date());
		cld.set(Calendar.DATE, cld.get(Calendar.DATE) - amount);
		String strDate = df.format(cld.getTime());
		return strDate;
	}
    
	// date类型转换为long类型
  	// date要转换的date类型的时间
  	public static long addDaysToLong(Long dateLong,int amount) throws ParseException {
  		Date date=longToDate(dateLong,"yyyy-MM-dd HH:mm:ss");
		Calendar cld = Calendar.getInstance();
		cld.setTime(date);
		cld.set(Calendar.DATE, cld.get(Calendar.DATE) +amount);
		return cld.getTime().getTime();
  	}
  	
  	/*功能描述：当前时间与创建时间比较，如果大于等于[minutes]分钟，则返回True
     * 参数：创建时间
     */
  	public static Boolean isMinuteBefore(Long createdAt,int minutes) {
    	Date nowDate=new Date();
    	Long diffMiSeconds=nowDate.getTime()-createdAt;
    	BigDecimal diffMiSecondsBigDecimal=new BigDecimal(diffMiSeconds);
    	int iResult=diffMiSecondsBigDecimal.compareTo(new BigDecimal(1000*60*minutes));				//当前时间与创建时间比较
    	return  (iResult>=0);
    }


    /**
     * 获取当年的开始时间戳
     *
     * @param timeStamp 毫秒级时间戳
     * @param timeZone  如 GMT+8:00
     * @return
     */
    public static Long getYearStartTime(Long timeStamp, String timeZone) {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTimeZone(TimeZone.getTimeZone(timeZone));
        calendar.setTimeInMillis(timeStamp);
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.DATE, 0);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTimeInMillis();
    }

    public static void main(String[] args) throws ParseException {
        Long yearStartTime = getYearStartTime(System.currentTimeMillis(), "GMT+8:00");
        System.out.println(HCDateUtils.longToString(yearStartTime,HCDateUtils.FORMATTIME));
    }
}
